<!--
    表格
    @params: url  数据请求路径， 返回promise的方法
    @params: tree Boolean 是否是表格树结构
             lazy 异步加载 表格树数据
             @load 方法 lazy 一起使用
    @params: response 配置返回参数字段
              {                             res: {
                data: 获取数据字段              data: {
                list: 获取列表字段                   list: [],
                pageObj: 返回的分页信息是否是对象      pageObj: {
                resultCode: 返回的结果码                pageSize: 10,
                pageSize: 每页字段                     pageNum: 1,
                pageNum: 当前页字段                    totalRow: 100
                                                    }
                totalRow: 数据总数字段            },

              }                                 resultCode: 0
                                              }
    @params: page 分页配置
            pageSize: 查询请求的pageSize字段                  query: {            query: {
            pageNum: 查询请求的pageNum字段                      pageSize: 10,        pageObj: {
            pageObj: 查询请求的page是否是对象                    pageNum: 1             pageSize: 10,
            layout: 分页的布局, 参考element-ui的page的layout   }                        pageNum: 1
                                                                                   }
                                                                                }
    @params: successCode 成功码 0
    @params: pageSize 页数量
    @params: selectType  select／多选  radio／多选  false
    @slot="head-right" 头部右边
    @slot="search-tool"  搜索
    @slot="opr-tool"   表头的操作栏
    @slot="table-col"   表格的列
-->

<template>
    <div class="table-panel">
        <div v-if="title" class="t-title">
            <span v-html="title"></span>
            <div class="tips-right"><slot name="head-right"></slot></div>
        </div>
        <div class="search-tool" v-if="$slots['search-tool']">
            <slot name="search-tool"></slot>
        </div>
        <div class="opr-tool" v-if="$slots['opr-tool']">
            <slot name="opr-tool"></slot>
        </div>
        <el-table
            ref="table"
            :data="tableData"
            v-loading="tableloading"
            @selection-change="handleSelectionChange"
            @select-all="selectAll"
            @select="handleRowSelect"
            @row-click="handleRowClick"
            v-bind="$attrs">
            <el-table-column
                v-if="selectType"
                type="selection"
                width="55"
                align="center"
                :selectable="handleCheckSelectable"></el-table-column>
            <el-table-column
                v-if="showIndex"
                width="55"
                label="序号"
                align="center">
                <template v-slot="{ $index }">{{ $index + 1 }}</template>
              </el-table-column>
            <slot></slot>
            <div class="empty-img" slot="empty">
                <img src="~images/empty.png" />
            </div>
        </el-table>
        <el-pagination
            v-if="page"
            @current-change="handleCurrentChange"
            :page-size="pageSize"
            :current-page="currentPage"
            :layout="page.layout"
            :total="total"></el-pagination>
        <slot name="bottom"></slot>
    </div>
</template>
<script>
import { deepClone } from '@/utils'
export default {
    props: {
        title: String,
        tree: Boolean,
        url: {
            type: [Function, Boolean],
            default: false
        },
        dataValue: {
            type: Array,
            default: () => []
        },
        response: {
            type: Object,
            default: () => {
                return {
                    data: 'data',
                    list: 'items',
                    resultCode: 'code',
                    pageObj: false,
                    totalRow: 'totalRow'
                }
            }
        },
        page: {
            type: [Object, Boolean],
            default: () => {
                return {
                    pageSize: 'pageSize',
                    pageNum: 'pageNum',
                    pageObj: 'pageVo',
                    layout: 'total, prev, pager, next, jumper'
                }
            }
        },
        successCode: {
            type: [Number, String],
            default: 0
        },
        pageSize: {
            type: Number,
            default: 10
        },
        selectType: {
            type: [Boolean, String],
            default: 'select'
        },
        autoLoad: {
            type: Boolean,
            default: false
        },
        selectedIds: {
            type: Array,
            default: () => []
        },
        checkSelectable: {
            type: Function,
            default: () => {
                return true
            }
        },
        formatter: {
            type: [Boolean, Function],
            default: false
        },
        showIndex: {
            type: Boolean,
            default: true
        }
    },
    data () {
        return {
            tableloading: false,
            total: 0,
            tableData: [],
            query: {},
            selectRow: []
        }
    },
    created () {
        this.initPageObj()
        if (this.url && typeof this.url === 'function') {
            this.autoLoad && this.loadData(this.query)
        } else {
            this.initStaticData(this.dataValue, 1)
        }
    },
    methods: {
        loadData (params) {
            const { data, resultCode, list, pageObj, totalRow } = this.response
            this.tableloading = true
            this.url(params)
                .then((res) => {
                    const resultData = data ? res[data] : res
                    this.tableloading = false
                    if (+res[resultCode] === +this.successCode) {
                        this.$emit('on-success', res)
                        if (typeof this.formatter === 'function') {
                            this.tableData = this.formatter(res)
                        } else {
                            this.tableData = resultData[list]
                        }
                        this.$nextTick(() => {
                            this.setSelection()
                        })
                        if (pageObj) {
                            this.total = resultData[pageObj][totalRow]
                        } else {
                            this.total = resultData[totalRow]
                        }
                    } else {
                        this.$emit('onError', res)
                    }
                })
                .catch((err) => {
                    this.$emit('onError', err)
                    this.tableloading = false
                })
        },
        refresh () {
            this.loadData(this.query)
        },
        initStaticData (dataList, pageNum) {
            const list = deepClone(dataList)
            this.total = list.length
            this.tableData = list.slice(
                this.pageSize * (pageNum - 1),
                this.pageSize * pageNum
            )
        },
        search (params) {
            this.setQueryPage(1)
            const p = Object.assign({}, this.query, params)
            this.query = deepClone(p)
            if (this.url && typeof this.url === 'function') {
                this.loadData(this.query)
            } else {
                this.initStaticData(this.dataValue, 1)
            }
        },
        handleCurrentChange (curpage) {
            this.$emit('changePage', curpage)
            this.setQueryPage(curpage)
            if (this.url && typeof this.url === 'function') {
                this.loadData(this.query)
            } else {
                this.initStaticData(this.dataValue, curpage)
            }
        },
        handleRowClick (row) {
            this.$emit('rowClick', row)
            if (this.selectType === 'radio') {
                this.$emit('select-change', [row])
                if (this.selectRow.length > 0) {
                    this.$refs.table.clearSelection()
                }
            }
            this.$refs.table.toggleRowSelection(row)
        },
        handleSelectionChange (val) {
            this.selectRow = val
            if (this.selectType === 'select') {
                this.$emit('select-change', val)
            }
        },
        setQueryPage (curpage) {
            const { pageNum, pageObj } = this.page
            if (pageObj) {
                this.query[pageObj][pageNum] = curpage
            } else {
                this.query[pageNum] = curpage
            }
        },
        initPageObj () {
            const { pageSize, pageNum, pageObj } = this.page
            const obj = {}
            if (pageObj) {
                obj[pageObj] = {}
                obj[pageObj][pageSize] = this.pageSize
                obj[pageObj][pageNum] = 1
            } else {
                obj[pageSize] = this.pageSize
                obj[pageNum] = 1
            }
            this.query = deepClone(obj)
        },
        handleRowSelect (val, row) {
            this.$nextTick(() => {
                if (this.selectType === 'radio') {
                    this.handleRowClick(row)
                }
            })
        },
        selectAll () {
            if (this.selectType === 'radio') {
                this.$refs.table.clearSelection()
            }
        },
        setSelection () {
            this.$refs.table.clearSelection()
            this.selectedIds.forEach((row) => {
                const itemObj = this.tableData.find(
                    (item) => item.id === row.id
                )
                if (itemObj) {
                    this.$refs.table.toggleRowSelection(itemObj)
                }
            })
        },
        handleCheckSelectable (row) {
            return this.checkSelectable(row)
        }
    },
    computed: {
        currentPage () {
            const { pageNum, pageObj } = this.page
            if (pageObj) {
                return this.query[pageObj][pageNum]
            } else {
                return this.query[pageNum]
            }
        }
    },
    watch: {
        dataValue: {
            deep: true,
            handler (newVal) {
                this.initStaticData(newVal, 1)
            }
        },
        selectedIds: {
            deep: true,
            handler () {
                this.$nextTick(() => {
                    this.setSelection()
                })
            }
        }
    }
}
</script>
<style scoped lang="scss"></style>
